package org.dromara.admin.ocr.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.admin.domain.bo.OrderBo;
import org.dromara.admin.domain.vo.OrderVo;
import org.dromara.admin.enums.OrderStatus;
import org.dromara.admin.enums.SigningStatus;
import org.dromara.admin.ocr.service.ContractSignService;
import org.dromara.admin.service.IOrderService;
import org.dromara.common.core.domain.R;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.vo.SysOssVo;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

/**
 * 合同签署
 *
 * @author Lion Li
 */
@Slf4j
@RestController
@RequestMapping("/contract")
@RequiredArgsConstructor
public class ContractSignController {

    private final ContractSignService contractSignService;

    private final IOrderService orderService;

    /**
     * 0. 查询用户是否进行签约流程
     */
    @PostMapping("/auth/{orderId}")
    public R<JsonNode> querySigningProcess(@PathVariable Long orderId) {
        try {
            return R.ok("查询签署进度成功", contractSignService.querySigningProcess(orderId));
        } catch (Exception e) {
            return R.fail("查询签署进度失败: " + e.getMessage());
        }
    }

    /**
     * 1. 发起个人三要素认证
     */
    @PostMapping("/auth/personal")
    public R<JsonNode> authPersonal() {
        Map<String, Object> req = new HashMap<>();
        try {
            Long userId = LoginHelper.getUserId();
            req.put("user_id", userId);
            return R.ok("个人三要素认证发起成功", contractSignService.authPersonal(req));
        } catch (Exception e) {
            return R.fail("个人三要素认证发起失败: " + e.getMessage());
        }
    }

    /**
     * 1.1 企业运营商三要素认证
     */
    @PostMapping("/auth/enterprise")
    public R<JsonNode> authEnterprise() {
        Map<String, Object> req = new HashMap<>();
        try {
            Long userId = LoginHelper.getUserId();
            req.put("user_id", userId);
            return R.ok("企业认证发起成功", contractSignService.authEnterprise(req));
        } catch (Exception e) {
            return R.fail("企业认证发起失败: " + e.getMessage());
        }
    }

    /**
     * 2. 校验验证码
     */
    @PostMapping("/auth/verify")
    public R<JsonNode> verifyCaptcha(@RequestBody Map<String, Object> req) {
        try {
            return R.ok("验证码校验成功", contractSignService.verifyCaptcha(req));
        } catch (Exception e) {
            return R.fail("验证码校验失败: " + e.getMessage());
        }
    }

    /**
     * 2.1.重新发送认证验证码
     */
    @PostMapping("/auth/resend")
    public R<JsonNode> resendCaptcha(@RequestBody Map<String, Object> req) {
        try {
            return R.ok("验证码重新发送成功", contractSignService.resendCaptcha(req));
        } catch (Exception e) {
            return R.fail("验证码重新发送失败: " + e.getMessage());
        }
    }

    /**
     * 3. 添加个人用户
     */
    @PostMapping("/user/add")
    public R<String> addPersonalUser(@RequestBody Map<String, String> req) {
        try {
            return R.ok("用户添加成功", contractSignService.addPersonalUser(req.get("serialNo")));
        } catch (Exception e) {
            return R.fail("用户添加失败: " + e.getMessage());
        }
    }

    /**
     * 3.1. 添加企业用户信息
     */
    @PostMapping("/user/addEnterprise")
    public R<String> addEnterpriseUser(@RequestBody Map<String, String> req) {
        try {
            return R.ok("企业用户添加成功", contractSignService.addEnterpriseUser(req.get("serialNo")));
        } catch (Exception e) {
            return R.fail("企业用户添加失败: " + e.getMessage());
        }
    }

    /**
     * 4. doc读取变量赋值
     */
    @SaIgnore
    @PostMapping("/sign/docRead")
    public R<JsonNode> docRead(@RequestBody Map<String, Object> req) {
        try {
            return R.ok("doc读取变量赋值成功", contractSignService.docRead(req));
        } catch (Exception e) {
            return R.fail("doc读取变量赋值失败: " + e.getMessage());
        }
    }

    /**
     * 5. 创建合同
     */
    @PostMapping("/contract/create")
    public R<JsonNode> createContract(@RequestBody Map<String, Object> req) {
        try {
            return R.ok("合同创建成功", contractSignService.createContract(req));
        } catch (Exception e) {
            return R.fail("合同创建失败: " + e.getMessage());
        }
    }

    /**
     * 6. 添加签署方
     */
    @PostMapping("/sign/addSigner")
    public R<JsonNode> addSigner(@RequestBody Map<String, Object> req) {
        try {
            return R.ok("签署方添加成功", contractSignService.addSigner(req));
        } catch (Exception e) {
            return R.fail("签署方添加失败: " + e.getMessage());
        }
    }

    /**
     * 7. 实名认证信息查询
     */
    @PostMapping("/sign/queryAuthInfo")
    public R<JsonNode> queryAuthInfo(@RequestBody Map<String, Object> req) {
        try {
            return R.ok("查询实名认证成功", contractSignService.queryAuthInfo(req));
        } catch (Exception e) {
            return R.fail("查询实名认证失败: " + e.getMessage());
        }
    }

    /**
     * 8. 接收用户签署完成通知
     *
     * @param request
     * @return
     */
    @SaIgnore
    @PostMapping("/receiveRefundNotify")
    public String receiveRefundNotify(HttpServletRequest request) {

        log.info("receive receiveNotify request:{}", request);

        JSONObject object = new JSONObject();
        Map<String, String[]> parameterMap = request.getParameterMap();
        parameterMap.forEach((param, values) -> {
            try {
                object.put(param, URLDecoder.decode(values[0] == null ? "" : values[0], "utf-8"));
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        });
        log.info("receive receiveNotify request2:{}", object);

        try {
            String status = object.getString("status");
            if ("2".equals(status)) {
                // 处理成功
                String contractNo = object.getString("contractNo"); // 合同唯一编码
                // 根据合同唯一编码查询order
                OrderVo orderVo = orderService.queryOrderByContractCode(contractNo);
                orderVo.setOrderStatus(OrderStatus.EFFECTING.getCode());
                orderVo.setSigningStatus(SigningStatus.SUCCESS.getCode());
                orderService.updateByBo(BeanUtil.copyProperties(orderVo, OrderBo.class));
            }
        } catch (Exception e) {
            return "ok";
        }
        return "ok";
    }

    /**
     * 9. 查询合同信息
     */
    @PostMapping("/queryContractInfo")
    public R<JsonNode> queryContractInfo(@RequestBody Map<String, Object> req) {
        try {
            return R.ok("查询合同信息成功", contractSignService.queryContractInfo(req));
        } catch (Exception e) {
            return R.fail("查询合同信息失败: " + e.getMessage());
        }
    }

    /**
     * 10. 下载合同
     */
    @PostMapping("/downloadContract")
    public R<JsonNode> downloadContract(@RequestBody Map<String, Object> req) {
        try {
            return R.ok("下载合同成功", contractSignService.downloadContract(req));
        } catch (Exception e) {
            return R.fail("下载合同失败: " + e.getMessage());
        }
    }
}
